﻿using System.IO;
using System.IO.Compression;

namespace RepX.Web.SessionState
{
    /// <summary>
    /// Helper library of common type conversions.
    /// </summary>
    public partial class Convert
    {
        public static byte[] Compress(byte[] uncompressedData)
        {
            // Skip compression when less than 512 bytes.
            if (uncompressedData.Length < 512) return uncompressedData;

            using (MemoryStream ms = new MemoryStream())
            {
                using (DeflateStream gzip = new DeflateStream(ms, CompressionLevel.Fastest, true))
                {
                    gzip.Write(uncompressedData, 0, uncompressedData.Length);
                }
                byte[] compressedBuffer = ms.ToArray();
                return compressedBuffer;
            }
        }

        public static byte[] Decompress(byte[] compressedData)
        {
            #region Try Deflate
            try
            {
                using (DeflateStream gzip = new DeflateStream(new MemoryStream(compressedData), CompressionMode.Decompress))
                {
                    byte[] uncompressedBuffer = ReadAllBytes(gzip);
                    return (uncompressedBuffer.Length < compressedData.Length ? compressedData : uncompressedBuffer);
                }
            }
            catch
            {
                // Decompression error.
            }
            #endregion

            #region Try GZip
            try
            {
                using (GZipStream gzip = new GZipStream(new MemoryStream(compressedData), CompressionMode.Decompress))
                {
                    byte[] uncompressedBuffer = ReadAllBytes(gzip);
                    return uncompressedBuffer;
                }
            }
            catch
            {
                // Decompression error.
            }
            #endregion

            // Assume NOT compressed.
            return compressedData;
        }

        private static byte[] ReadAllBytes(Stream stream)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                stream.CopyTo(ms);

                return ms.ToArray();
            }
        }
    }
}
